﻿using System;
using System.Collections;
using System.Collections.Specialized;
using System.Data;
using System.Reflection;
using AMS.Core.DataAccess;
using AMS.Core.Entities;
using VitCode.Castle.Entities;
using VitCode.Castle.Helper;

namespace AMS.Core.Importors
{
    public sealed class AssetTypeImportor : AbstractImportor
    {
        private const string CLASS = "类名称";
        private const string CLASSCODE = "类编码";
        private const string ITEM = "项名称";
        private const string ITEMCODE = "项编码";
        private const string LIST = "目名称";
        private const string LISTCODE = "目编码";
        private const string NODE = "节名称";
        private const string NODECODE = "节编码";
        private const string TYPECODE = "类别编码";
        private const string NAME = "类别名称";

       
        private const string KEY_WORD = "关键字";
        private const string m_ObjectKeyProName = "Name";
        private const string MEMO = "备注";

        

        private const string ObjectName = "类别编码";
        private const string OPERATE = "操作";
        private CoreDataAccess m_Access;

        private User m_CurrUser;
         

        private NameObjectDictionary m_nodObjects = new NameObjectDictionary();
        private NameObjectDictionary m_nodObjectsByTypeCode = new NameObjectDictionary();
        private NameValueCollection m_ProNameSet;

        private StringCollection m_scTypeCodes = new StringCollection();
        private StringCollection m_scNames = new StringCollection();

        public AssetTypeImportor(string path, string sheetName, User currentUserCode)
        {
            m_ErrorMessage = new ErrorResult();
            m_ErrorMessage.TableName = "出错信息";
            FilePath = path;
            SheetName = sheetName;
            m_IsTrans = true;
            m_CurrUser = currentUserCode;
            m_ImportNum = DataAccess.GetImportNum();
        }

        private NameValueCollection ProNameSet
        {
            get
            {
                if (m_ProNameSet == null) //简单属性绑定,用于DataRowToObject
                {
                    m_ProNameSet = new NameValueCollection();
                    m_ProNameSet.Add(CLASS, "Class");
                    m_ProNameSet.Add(CLASSCODE, "ClassCode");
                    m_ProNameSet.Add(ITEM, "Item");
                    m_ProNameSet.Add(ITEMCODE, "ItemCode");
                    m_ProNameSet.Add(LIST, "List");
                    m_ProNameSet.Add(LISTCODE, "ListCode");
                    m_ProNameSet.Add(NODE, "Node");
                    m_ProNameSet.Add(NODECODE, "NodeCode");
                    m_ProNameSet.Add(NAME,"Name");
                    m_ProNameSet.Add(TYPECODE,"TypeCode");

                    m_ProNameSet.Add(KEY_WORD, "KeyWord");
                    m_ProNameSet.Add(MEMO, "Memo");
                }
                return m_ProNameSet;
            }
        }

        private CoreDataAccess DataAccess
        {
            get
            {
                if (m_Access == null)
                    m_Access = new CoreDataAccess();
                return m_Access;
            }
        }

        protected override string[] Titles
        {
            get { return new[] { CLASS, CLASSCODE, ITEM,ITEMCODE,LIST,LISTCODE,NODE,NODECODE, TYPECODE,NAME, MEMO, KEY_WORD, OPERATE }; }
        }

        protected override object DataRowToObject(DataRow row)
        {
            string strKeyVal = Convert.ToString(NAME).Trim();
            bool isInsert = (ReturnColumnValue(row, OPERATE) == INSERT);

            AssetType result;
            if (isInsert)
            {
                result = new AssetType();
                result.Name = strKeyVal;
                result.ImportNum = m_ImportNum;
                InsertCount++;
                isInsert = true;
            }
            else
            {
                result = (AssetType)m_nodObjects[strKeyVal];
                UpdateCount++;
            }

            for (int i = 0; i < ProNameSet.Count; i++)
            {
                string strProName = ProNameSet.Get(i);
                string strColName = ProNameSet.GetKey(i);
                if (IsNeedToUpdateInfo(isInsert, row, strColName))
                {
                    string strColValue = ReturnColumnValue(row, strColName);
                    PropertyInfo pi = result.GetType().GetProperty(strProName);
                    if (pi != null)
                    {
                        if (pi.PropertyType == typeof (String)
                            || pi.PropertyType == typeof (Int16) || pi.PropertyType == typeof (Int32) ||
                            pi.PropertyType == typeof (Int64) || pi.PropertyType == typeof (Double))
                            pi.SetValue(result, strColValue, null);
                    }
                }
            }

 
            return result;
        }

        protected override void SaveObjects(IList objects)
        {
            if (IsTrans)
                DataAccess.BeginTransaction();
            try
            {
                foreach (Object obj in objects)
                {
                    DataAccess.SaveOrUpdate(obj);
                }
                if (IsTrans)
                    DataAccess.Commit();
            }
            catch (Exception e)
            {
                if (m_IsTrans)
                    DataAccess.RollBack();
                throw e;
            }
            finally
            {
                if (m_IsTrans)
                    DataAccess.CloseSession();
            }
        }

        protected override void GetDBRecordSet()
        {
            try
            {
                m_nodObjects = DataAccess.GetObjectsByKeyValues("AssetType", m_ObjectKeyProName, m_scNames);
                m_nodObjectsByTypeCode = DataAccess.GetObjectsByKeyValues("AssetType", "TypeCode", m_scTypeCodes);

                
            }
            finally
            {
                DataAccess.CloseSession();
            }
        }

        protected override ExcelHelper CreateExcelHelper(string path, string sheetName)
        {
            var helper = new ExcelHelper(path, sheetName);
            helper.NotRepleateColumns.AddColumnByName(NAME);
            helper.NotEmptyColumns.AddColumnByName(OPERATE);
            return helper;
        }

        protected override void CreateDBSearchCondition(DataRow row, ErrorResult errorResult, int excelRowNumber)
        {
            string Message = "";
            string strTypeCode = ReturnColumnValue(row, TYPECODE);
            string strObjKeyVal = ReturnColumnValue(row, NAME);


            string operate = Convert.ToString(row[OPERATE]).Trim();

            bool isInsert = (operate == INSERT);

            //控制非空字段的导入与更新操作
            var insertNoEmptyTitles =
                new[]
                    {
                         CLASS, CLASSCODE, ITEM,ITEMCODE,LIST,LISTCODE,NODE,NODECODE, TYPECODE,NAME
                    };

            CheckInsertNoEmptyColumn(row, insertNoEmptyTitles, isInsert, errorResult, excelRowNumber);

            //不允许清除内容的列
            var updateNoDeleteTitles = new[]
                                           {
                                               NAME, TYPECODE
                                           };

            CheckUpdateNoDeleteField(row, updateNoDeleteTitles, isInsert, errorResult, excelRowNumber);


            if (!CheckFieldLength(row, NAME, 1, 50, out Message))
                errorResult.SetMessage(excelRowNumber, Message);
            else if (!m_scNames.Contains(strObjKeyVal))
                m_scNames.Add(strObjKeyVal);

            if (!CheckFieldLength(row, TYPECODE, 1, 50, out Message))
                errorResult.SetMessage(excelRowNumber, Message);
            else if (!m_scTypeCodes.Contains(strTypeCode))
                m_scTypeCodes.Add(strTypeCode);

           

            if (!CheckFieldLength(row, CLASS, 0, 50, out Message))
                errorResult.SetMessage(excelRowNumber, Message);
            if (!CheckFieldLength(row, CLASSCODE, 0, 50, out Message))
                errorResult.SetMessage(excelRowNumber, Message);
            if (!CheckFieldLength(row, ITEM, 0, 50, out Message))
                errorResult.SetMessage(excelRowNumber, Message);
            if (!CheckFieldLength(row, ITEMCODE, 0, 50, out Message))
                errorResult.SetMessage(excelRowNumber, Message);
            if (!CheckFieldLength(row, LIST, 0, 50, out Message))
                errorResult.SetMessage(excelRowNumber, Message);
            if (!CheckFieldLength(row, LISTCODE, 0, 50, out Message))
                errorResult.SetMessage(excelRowNumber, Message);
            if (!CheckFieldLength(row, NODE, 0, 50, out Message))
                errorResult.SetMessage(excelRowNumber, Message);
            if (!CheckFieldLength(row, NODECODE, 0, 50, out Message))
                errorResult.SetMessage(excelRowNumber, Message);

            if (!CheckFieldLength(row, MEMO, 0, 500, out Message))
                errorResult.SetMessage(excelRowNumber, Message);

            if (!CheckFieldLength(row, KEY_WORD, 0, 100, out Message))
                errorResult.SetMessage(excelRowNumber, Message);
        }

        protected override void CheckInDb(DataRow row, int excelRowNumber, ErrorResult errorResult)
        {
            bool isInsert = (ReturnColumnValue(row, OPERATE) == INSERT);
            string msg = "";
            string strObjKeyProVal = ReturnColumnValue(row, NAME);
            string strCode = ReturnColumnValue(row, TYPECODE);

            if (isInsert)
            {
                if (CheckChildObjectExists(m_nodObjects, strObjKeyProVal, NAME, out msg))
                    errorResult.SetMessage(excelRowNumber,
                                           NAME + "为: [ " + strObjKeyProVal + " ] 的" + ObjectName +
                                           "已经存在不能导入");
                if (CheckChildObjectExists(m_nodObjectsByTypeCode, strCode, TYPECODE, out msg))
                    errorResult.SetMessage(excelRowNumber, TYPECODE + "为: [ " + strCode + " ] 的" + ObjectName + "已经存在不能导入");
            }
            else
            {
                if (!CheckChildObjectExists(m_nodObjects, strObjKeyProVal, NAME, out msg))
                    errorResult.SetMessage(excelRowNumber,
                                           NAME + "为: [ " + strObjKeyProVal + " ] 的" + ObjectName +
                                           "不存在不能更新");
                if (m_nodObjectsByTypeCode.Contains(strCode))
                {
                    var objByCode = (Site) (m_nodObjectsByTypeCode[strCode]);
                    if (!objByCode.Name.Equals(strObjKeyProVal) && objByCode.Code.Equals(strCode))
                        errorResult.SetMessage(excelRowNumber,
                                               TYPECODE + "为:'" + strCode + "'的已被其它的'" + ObjectName + "'占用(" +
                                               NAME + "为:'" + strObjKeyProVal + "'的" + ObjectName + "对象)");
                }
            }


          
        }
    }
}
